/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.landmark;

import java.io.FileWriter;
import java.net.SocketTimeoutException;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import org.htmlparser.Node;
import org.htmlparser.Parser;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.nodes.TagNode;
import org.htmlparser.nodes.TextNode;
import org.htmlparser.util.NodeIterator;
import org.htmlparser.util.NodeList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 *
 * @author computer
 */
public class SandPiperCat extends SwingWorker<Boolean, Boolean> {

    FileWriter fw = null;
    FileWriter errorFile = null;
    int fileNumber = 0;
    int pageNo;
    StringBuffer sb = new StringBuffer();
    Hashtable<String, String> htModelLinks = new Hashtable<String, String>();
    String status = "";
    JTextArea txtArea;
    String imageDirName = "./outputs/SandPiperImages";
    @Override
    protected Boolean doInBackground() throws Exception {
        start();
        return true;
    }

    @Override
    protected void done() {
        Util.taskCompleteMsg(status);
    }

    public void start() {
        try {
            String dirName = "./outputs";
            
            Util.createDirectory(dirName);
            Util.createDirectory(imageDirName);
//            String[] categoryViewAll = {"gear-packs.html"};//, "travel-accessories.html", "clearance.html"}; // The category name/code
            String[] categoryViewAll = {"healthy-lifestyle-series.html", "gear-packs.html", "travel-accessories.html", "clearance.html"}; // The category name/code

            txtArea = Util.createOutputFile("SandPiper");
            HelperBean helperBean = Util.getHelperBean();

            fw = new FileWriter(helperBean.getOutputFile());
            errorFile = new FileWriter(helperBean.getErrorFile());
            fw.write("Product_Link,Description,Product_Name, Image_Name\n");
            // Here we get all the search pages from page 0 to 9 which we know by seeing the site
            for (int i = 0; i < categoryViewAll.length; i++) {
                if (Util.getHelperBean().isTerminateCurrentProcess()) {
                    break;
                }
                String str = "http://shop.sandpiperca.com/index.php/" + categoryViewAll[i] + "?limit=all";
                txtArea.setText(str);
                txtArea.paintImmediately(txtArea.getVisibleRect());
                processCategoryPage(str, false);
            }

            txtArea.append("\nFiles are located at : \n" + helperBean.getOutputFile().getAbsolutePath() + "\n" + helperBean.getErrorFile().getAbsolutePath() + "\n");
            txtArea.append("Total products : " + htModelLinks.size() + "\n");
            txtArea.paintImmediately(txtArea.getVisibleRect());

            iterateCollection(htModelLinks);

            if (fw != null) {
                fw.close();
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (Exception e1) {
                // TODO: handle exception
            }
        }
        status = "Done processing.";
        if (Util.getHelperBean().isTerminateCurrentProcess()) {
            status = "Process Terminated";
        }
        txtArea.append("\n" + status);
    }

    /**
     *
     * @param htLinks
     */
    private void iterateCollection(Hashtable<String, String> htLinks) {
        try {
            Enumeration<String> keys = htLinks.keys();
            while (keys.hasMoreElements()) {
                if (Util.getHelperBean().isTerminateCurrentProcess()) {
                    break;
                }
                String key = (String) keys.nextElement();
                
                txtArea.append("Processing page: " + key + "\n");
                txtArea.paintImmediately(txtArea.getVisibleRect());
                
                sb = new StringBuffer();
                
                fw.write("\n");
                fw.write(key+",");
                processModels(htLinks.get(key).toString());
                fw.write(sb.toString().replaceAll("\n", "").replaceAll("\r", "").replaceAll(",", "#440;").replaceAll("    ", "").replaceAll("#IMAGENAME#", ",").replaceAll("#PRDTNAME#", ",").replaceAll("#DESCENDLMIT#", ","));                
                fw.flush();
            }
        } catch (Exception e) {
        }
    }

    /**
     *
     * @param aUrl
     */
    private void processModels(String aUrl) {
        try {
            Parser parser = Util.getParserFromUrl(aUrl, null);
            
            NodeList nl = parser.parse(null);
            
            NodeList tableNodes = nl.extractAllNodesThatMatch(new HasAttributeFilter("class", "product-tabs-content"), true);
            NodeList nodeList = tableNodes.extractAllNodesThatMatch(new HasAttributeFilter("class", "std"), true);
            Node targetTableNode = nodeList.elementAt(0);// retrives the table content where the description starts which we are intersetd in.			
            
            iterateTag(targetTableNode);
            sb.append("#DESCENDLMIT#");
            // Load the product name
            Elements elements = Util.getHelperBean().getInputHTML().getElementsByAttributeValue("class", "product-name");
            for( Element ele :  elements ) {
                sb.append(ele.text());
                sb.append("#PRDTNAME#");
            }
            
            //Save the images
            String imageUrl = Util.getHelperBean().getInputHTML().getElementById("image").attr("src");
            Util.saveImage(imageUrl , imageDirName , null);             
            sb.append(imageUrl.substring(imageUrl.lastIndexOf("/")+1,imageUrl.length()) );
            sb.append("#IMAGENAME#");
        } catch (SocketTimeoutException e) {
            processModels(aUrl);                            
        } catch (Exception e) {
            try {                
                errorFile.write(aUrl + " \n" + e.getMessage() + " \n");
                errorFile.flush();                
            } catch (Exception e1) {                
            }
        } 
    }

    /**
     *
     * @param aNodeList
     */
    private void iterateTag(Node aNodeList) {
        if (aNodeList instanceof TextNode) {
            // downcast to TextNode
            TextNode text = (TextNode) aNodeList;

            sb.append(text.getText());
        } else if (aNodeList instanceof TagNode) {
            // downcast to TagNode
            TagNode tag = (TagNode) aNodeList;

            NodeList nl = tag.getChildren();
            if (null != nl) {
                try {
                    for (NodeIterator i = nl.elements(); i.hasMoreNodes();) {
                        iterateTag(i.nextNode());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void processCategoryPage(String aUrl, boolean isModelPage) {
        try {
            Document doc = Jsoup.connect(aUrl).get();

            Elements elements = doc.select("h2.product-name").select("a[href]");

            for (Element element : elements) {                
                String absoluteUrl = element.attr("abs:href");
                //System.out.println(absoluteUrl);
                htModelLinks.put(absoluteUrl, absoluteUrl);
            }
        }catch (SocketTimeoutException e) {
            processCategoryPage(aUrl,isModelPage);                            
        } catch (Exception e) {
            try {                
                errorFile.write(aUrl + " \n" + e.getMessage() + " \n");
                errorFile.flush();                
            } catch (Exception e1) {                
            }
        } 
    }

}

